package com.gegong.imr.client.tasks.vbox;


import com.alibaba.fastjson.JSONObject;
import com.gegong.imessage.dto.TVmTask;
import com.gegong.imessage.utils.MapBuilder;
import com.gegong.imr.client.IMessageClientProfiles;
import com.gegong.imr.client.bean.TaskCmd;
import com.gegong.imr.client.config.ImrCenterConfig;
import com.gegong.imr.client.config.ImrClientConfig;
import com.gegong.imr.client.tasks.AbstractProcessCommandTask;
import com.gegong.imr.client.tasks.CenterResponse;
import com.gegong.imr.client.tasks.TaskException;
import com.gegong.imr.client.utils.http.HttpRequestUtils;
import com.gegong.imr.client.utils.os.MachineUtils;
import com.gegong.imr.client.vbox.cmd.IVBoxCmd;
import com.gegong.imr.client.vbox.cmd.VmManageOption;
import com.gegong.imr.client.vbox.cmd.VmPowerOption;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.virtualbox_5_2.VirtualBoxManager;

import java.util.HashMap;
import java.util.Objects;

/**
 * 用于轮询任务并执行
 *
 * @author dongjak
 */
@Component
@Slf4j
@Profile(IMessageClientProfiles.VBOX)
public class VboxProcessCommandTask extends AbstractProcessCommandTask {

    private final ImrCenterConfig imrCenterConfig;
    private final ImrClientConfig clientConfig;
    private final VirtualBoxManager virtualBoxManager;
    private final ImrCenterConfig centerConfig;

    @Autowired
    public VboxProcessCommandTask(ImrCenterConfig imrCenterConfig, VirtualBoxManager virtualBoxManager, ImrClientConfig clientConfig,
                                  ImrCenterConfig centerConfig) {
        super(imrCenterConfig);
        this.imrCenterConfig = imrCenterConfig;
        this.virtualBoxManager = virtualBoxManager;
        this.clientConfig = clientConfig;
        this.centerConfig = centerConfig;
    }

    @Override
    public void run() {
        log.info("从服务器查询任务...");
        try {
            log.info("本机上的虚拟机列表{}", virtualBoxManager.getVBox().getMachines());
            CenterResponse responseEntity = HttpRequestUtils.postJsonWithJsonRes(imrCenterConfig.urlForGetClientCurrentTask(),
                    JSONObject.toJSONString(MapBuilder.newMapBuilder(new HashMap<>())
                            .put("client_code", MachineUtils.getCPUSerialNumber())
                            .put("virtual_num", virtualBoxManager.getVBox().getMachines().size())
                            .map()));

            if (Objects.isNull(responseEntity))
                throw new HttpException("服务器没有任何响应");
            if (!responseEntity.isSuccessful())
                throw new TaskException(responseEntity.getMsg());
            TVmTask machineTask = responseEntity.getData().toJavaObject(TVmTask.class);
            log.info("正在执行任务..." + machineTask);

            IVBoxCmd boxCmd = TaskCmd.fromValue(machineTask.getTaskCmd()).build(virtualBoxManager, machineTask.getVirtualName());
            IVBoxCmd.Progress cmdProgress = null;

            //根据不同的命令指定参数
            switch (TaskCmd.fromValue(machineTask.getTaskCmd())) {
                case copy_virtual:
                case modify_virtual:
                    cmdProgress = boxCmd.execute(machineTask, clientConfig.getTemplateVmName());
                    break;
                case start_virtual:
                    cmdProgress = boxCmd.execute(VmPowerOption.ON);
                    break;
                case shutdown_virtual:
                    cmdProgress = boxCmd.execute(VmPowerOption.OFF);
                    break;
                case restart_virtual:
                    cmdProgress = boxCmd.execute(VmPowerOption.RESTART);
                    break;
                case del_virtual:
                    cmdProgress = boxCmd.execute(VmManageOption.DELETE);
                    break;
                default:
                    throw new UnsupportedOperationException("不支持的命令");
            }


            if (cmdProgress.getResultCode() == IVBoxCmd.Progress.RESULT_FAILURED)
                throw new Exception(cmdProgress.getErrorInfo());

            //.execute(null);
            log.info("任务执行完毕");
            log.info("上报任务状态...");
            reportExecutedStatus(machineTask.getTaskId(),
                    cmdProgress.getResultCode(),
                    Objects.nonNull(cmdProgress.getErrorInfo()) ? cmdProgress.getErrorInfo().getMessage() : null);
            //log.info("上报客户端最新状态...");
            //reportClient();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
